#include "gamecontrol.h"

GameControl* GameControl::instance = nullptr;

GameControl::GameControl() {
    this->setParent(Widget::widget);//设置父类
}

void GameControl::BGMove(){
    mBackGround1.moveBy(0,2);//移动量
    mBackGround2.moveBy(0,2);
    if(mBackGround1.y() >= mBackGround1.pixmap().height()){
        mBackGround1.setY(-mBackGround1.pixmap().height());
    }
    else if(mBackGround2.y() >= mBackGround2.pixmap().height()){
        mBackGround2.setY(-mBackGround2.pixmap().height());
    }
}


void GameControl::GameInit(){

    //设置视图的父类
    mGameView.setParent(Widget::widget);

    LoadStartScene();//开始场景初始化

    mBGMoveTimer = new QTimer(this);
    mPlaneMoveTimer = new QTimer(this);
    mPlaneShootTimer = new QTimer(this);
    mEnemyCreatorTimer = new QTimer(this);
    mBulletMoveTimer = new QTimer(this);
    mEnemyMoveTimer = new QTimer(this);
    mEnemyFireTimer = new QTimer(this);

    //绑定定时器处理函数
    connect(mBGMoveTimer,&QTimer::timeout,this,&GameControl::BGMove);
    connect(mPlaneMoveTimer,&QTimer::timeout,this,&GameControl::PlaneMove);
    connect(mPlaneShootTimer,&QTimer::timeout,this,&GameControl::PlaneBulletShoot);
    connect(mEnemyCreatorTimer,&QTimer::timeout,this,&GameControl::CreateEnemy);
    connect(mBulletMoveTimer,&QTimer::timeout,[this](){

        //子弹移动
        for (auto& bullet : mBulletList){
            bullet->BulletMove();
        }

        //碰撞检测
        Collision();
    });

    connect(mEnemyMoveTimer,&QTimer::timeout,[this](){
        //敌人移动
        for (auto& enemy : mEnemyList){
            enemy->EnemyMove();
        }
    });

    connect(mEnemyFireTimer, &QTimer::timeout, [this](){
        static QSoundEffect soundEffect(this);
        soundEffect.setSource(QUrl("qrc:/audio/CameraRoll/BulletEnemy .wav"));

        for (auto& enemy : mEnemyList){
            int randomIndex = QRandomGenerator::global()->bounded(4);
            Bullet* bullet = new Bullet(QPointF(enemy->x() + enemy->pixmap().width()/2,
                                                enemy->y() + enemy->pixmap().height()),
                                                enemyBulletSprites[randomIndex], Bullet::BT_Enemy, QPointF(0, 0.5));
            soundEffect.play();
            //添加到场景
            mGameScene.addItem(bullet);

            //添加到子弹管理器
            mBulletList.append(bullet);
        }
    });
}

void GameControl::LoadStartScene(){
    mStartScene.setSceneRect(QRect(0,0,GameDefine::ScreenWidth,GameDefine::ScreenHeight));//游戏开始场景大小
    //开始场景初始化
    mStartScene.addPixmap(QPixmap(":/CameraRoll/startScene.jpg"));
    auto startBtn = new QToolButton();
    startBtn->resize(170,170);
    startBtn->setIcon(QIcon(":/CameraRoll/startButton.jpg"));
    startBtn->setIconSize(QSize(170,170));
    startBtn->move(171,400);
    //开始游戏点击音效
    connect(startBtn,&QToolButton::clicked,this,[this](){

        //加载开始场景
        this->LoadGameScene();
        //开始游戏
        this->GameStart();

    });

    mStartScene.addWidget(startBtn);

    //设置当前场景为开始场景
    mGameView.setScene(&mStartScene);
    mGameView.show();
}

void GameControl::LoadGameScene()
{
    mGameScene.setSceneRect(QRect(0,0,GameDefine::ScreenWidth,GameDefine::ScreenHeight));//游戏进行场景大小

    mBackGround1.setPixmap(QPixmap(":/CameraRoll/GameScene.jpg"));
    mBackGround2.setPixmap(QPixmap(":/CameraRoll/GameScene.jpg"));
    myPlane.setPixmap(QPixmap(":/CameraRoll/plane.jpg"));
    //设置元素位置

    mBackGround2.setPos(0,-mBackGround2.pixmap().height());

    //图片元素添加到场景
    mGameScene.addItem(&mBackGround1);
    mGameScene.addItem(&mBackGround2);
    mGameScene.addItem(&myPlane);

    //设置场景
    mGameView.setScene(&mStartScene);

    //设置当前场景为游戏场景
    mGameView.setScene(&mGameScene);
    mGameView.show();

    //设置音频源
    this->mMediaBG = new QSoundEffect(this);
    this->mMediaBG->setSource(QUrl("qrc:/audio/CameraRoll/startGame.wav"));
    this->mMediaBG->play();
    //播放游戏背景音效
    this->mMediaBG = new QSoundEffect(this);
    this->mMediaBG->setSource(QUrl("qrc:/audio/CameraRoll/GameBGM.wav"));
    this->mMediaBG->play();
}

void GameControl::GameStart()
{
    //开启定时器
    mBGMoveTimer->start(GameDefine::BackgroundUpdateTime);
    mPlaneMoveTimer->start(GameDefine::PlayerMoveUpdateTime);
    mPlaneShootTimer->start(GameDefine::PlaneShootUpdateTime);
    mBulletMoveTimer->start(GameDefine::BulletMoveUpdateTime);
    mEnemyCreatorTimer->start(GameDefine::EnemyCreateUpdateTime);
    mEnemyMoveTimer->start(GameDefine::EnemyMoveUpdateTime);
    mEnemyFireTimer->start(GameDefine::EnemyFireUpdateTime);

    enemyBulletSprites.append(QPixmap(":/CameraRoll/EnemyBullet1.png"));
    enemyBulletSprites.append(QPixmap(":/CameraRoll/EnemyBullet2.png"));
    enemyBulletSprites.append(QPixmap(":/CameraRoll/EnemyBullet3.png"));
    enemyBulletSprites.append(QPixmap(":/CameraRoll/EnemyBullet4.png"));

    for (auto& sprite : enemyBulletSprites) {
        sprite = sprite.scaled(sprite.width() * 2, sprite.height() * 2);
    }
}

void GameControl::GameOver()
{
    mBGMoveTimer->stop();
    mPlaneMoveTimer->stop();
    mPlaneShootTimer->stop();
    mBulletMoveTimer->stop();
    mEnemyCreatorTimer->stop();
    mEnemyMoveTimer->stop();
    mEnemyFireTimer->stop();

    delete yoshi;
    yoshi = nullptr;

    QPixmap failSprite(":/CameraRoll/lose.jpg");
    failSprite = failSprite.scaled(GameDefine::ScreenWidth, GameDefine::ScreenHeight);
    QGraphicsPixmapItem* failScreen = new QGraphicsPixmapItem(failSprite);

    mMediaBG->setSource(QUrl("qrc:/audio/CameraRoll/Gamefail.wav"));
    mMediaBG->play();
    mGameScene.addItem(failScreen);
}

void GameControl::GameWin() {
    mBGMoveTimer->stop();
    mPlaneMoveTimer->stop();
    mPlaneShootTimer->stop();
    mBulletMoveTimer->stop();
    mEnemyCreatorTimer->stop();
    mEnemyMoveTimer->stop();
    mEnemyFireTimer->stop();

    delete yoshi;
    yoshi = nullptr;

    QPixmap winSprite(":/CameraRoll/victory.png");

    QGraphicsPixmapItem* winScreen = new QGraphicsPixmapItem(winSprite);
    winScreen->setPos(mGameScene.width()/2 - winSprite.width()/2, mGameScene.height()/2 - winSprite.height()/2);
    mGameScene.addItem(winScreen);
    mMediaBG->setSource(QUrl("qrc:/audio/CameraRoll/victory.wav"));
    mMediaBG->play();

}



void GameControl::PlaneBulletShoot(){
    //创建子弹
    QPixmap bulletImg(":/CameraRoll/Bullet.png");
    QPoint pos(myPlane.x() + myPlane.boundingRect().width() / 2, myPlane.y());
    Bullet* bullet = new Bullet(pos,bulletImg,Bullet::BT_Player, QPointF(0, -1));

    static QSoundEffect soundEffect(this);
    soundEffect.setSource(QUrl("qrc:/audio/CameraRoll/BulletPlane.wav"));
    soundEffect.play();

    //添加到场景
    mGameScene.addItem(bullet);

    //添加到子弹管理器
    mBulletList.append(bullet);
}

void GameControl::CreateEnemy(){
    QPixmap pixmap(":/CameraRoll/enemy1.jpg");
    int randX = QRandomGenerator::global()->bounded(512 - pixmap.width());
    Enemy* enemy1 = new Enemy(QPoint(randX,0),pixmap);

    //添加到场景
    mGameScene.addItem(enemy1);

    //添加到管理器
    mEnemyList.append(enemy1);
}


void GameControl::Collision() {
    QList<QGraphicsItem*> bulletsToRemove;
    QList<QGraphicsItem*> enemiesToRemove;

    // 碰撞音效
    static QSoundEffect soundEffect(this);
    soundEffect.setSource(QUrl("qrc:/audio/CameraRoll/GetBullet .wav"));

    // 自机子弹和敌机的碰撞检测
    for (auto bullet : mBulletList) {
        if (bullet->type() == Bullet::BT_Player) {
            if (yoshi && bullet->collidesWithItem(yoshi)) {
                yoshi->hit();

                mGameScene.removeItem(bullet);

                bulletsToRemove.append(bullet);
                soundEffect.play();

                break;
            }

            for (auto enemy : mEnemyList) {
                if (bullet->collidesWithItem(enemy)) {
                    // 播放碰撞音效
                    soundEffect.play();

                    // 移除场景
                    mGameScene.removeItem(bullet);
                    mGameScene.removeItem(enemy);

                    bulletsToRemove.append(bullet);
                    enemiesToRemove.append(enemy);
                    enemiesDunked++;

                    if (enemiesDunked == GameDefine::EnemyKillRequirment) {
                        mEnemyCreatorTimer->stop();
                        CreateBoss();
                    }

                    break;
                }
            }

        } else if (bullet->type() == Bullet::BT_Enemy) {
            if (bullet->collidesWithItem(&myPlane)) {
                GameOver();
                // 可以在这里添加玩家受伤或死亡的处理逻辑
                bulletsToRemove.append(bullet);
                mGameScene.removeItem(bullet);

                break;
            }
        }

        // 检查子弹是否超出屏幕边界
        if (bullet->x() < 0 ||
            bullet->x() > GameDefine::ScreenWidth ||
            bullet->y() < 0 ||
            bullet->y() > GameDefine::ScreenHeight) {
            bulletsToRemove.append(bullet);
            mGameScene.removeItem(bullet);
        }
    }

    // 敌机和屏幕边界的碰撞检测
    for (auto enemy : mEnemyList) {
        if (enemy->x() < 0 ||
            enemy->x() > GameDefine::ScreenWidth ||
            enemy->y() < 0 ||
            enemy->y() > GameDefine::ScreenHeight) {
            enemiesToRemove.append(enemy);
            mGameScene.removeItem(enemy);
        }
    }

    // 在外部循环中统一删除子弹
    for (auto bullet : bulletsToRemove) {
        mBulletList.removeOne(bullet);
        delete bullet; // 释放内存
    }

    // 在外部循环中统一删除敌机
    for (auto enemy : enemiesToRemove) {
        mEnemyList.removeOne(enemy);
        delete enemy; // 释放内存
    }
}

void GameControl::CreateBoss() {
    yoshi = new Boss(QPixmap(":/CameraRoll/Boss.png"));

    mGameScene.addItem(yoshi);

    connect(yoshi, &Boss::bossDefeated, this, &GameControl::GameWin);
    connect(yoshi, &Boss::bossShoot, this, &GameControl::BossShoot);
}

void GameControl::BossShoot() {
    const int MAX_WAY = 16;
    static QSoundEffect soundEffect(this);

    int randomXOffset = QRandomGenerator::global()->bounded(128) - 64;
    int randomYOffset = QRandomGenerator::global()->bounded(128) - 64;
    float randomAngleOffset = QRandomGenerator::global()->generateDouble() * GameDefine::PI * 2;
    const float bulletSpeed = 0.5;

    for (int way = 0; way < MAX_WAY; ++way) {
        int randomIndex = QRandomGenerator::global()->bounded(4);

        float angle = way * 2 * GameDefine::PI / MAX_WAY + randomAngleOffset;
        Bullet* bullet = new Bullet(QPointF(yoshi->x() + yoshi->pixmap().width() / 2 + randomXOffset,
                                            yoshi->y() + yoshi->pixmap().height() / 2 + randomYOffset),
                                    enemyBulletSprites[randomIndex], Bullet::BT_Enemy, QPointF(std::cos(angle) * bulletSpeed, std::sin(angle) * bulletSpeed));
        soundEffect.setSource(QUrl("qrc:/audio/CameraRoll/BulletEnemy .wav"));
        //添加到场景
        mGameScene.addItem(bullet);

        //添加到子弹管理器
        mBulletList.append(bullet);
    }
}

void GameControl::PlaneMove(){
    for(int keyCode : mKeyList){
        switch(keyCode){
        case Qt::Key_W: myPlane.moveBy(0,-1 * myPlane.MoveSpeed());break;
        case Qt::Key_S: myPlane.moveBy(0,1 * myPlane.MoveSpeed());break;
        case Qt::Key_A: myPlane.moveBy(-1 * myPlane.MoveSpeed(),0);break;
        case Qt::Key_D: myPlane.moveBy(1 * myPlane.MoveSpeed(),0);break;
        }
    }

    //边界判断
    if(myPlane.x() < 0){
        myPlane.setX(0);
    }
    if(myPlane.y() < 0){
        myPlane.setY(0);
    }
    if(myPlane.x() > GameDefine::ScreenWidth - myPlane.pixmap().width()){
        myPlane.setX(GameDefine::ScreenWidth - myPlane.pixmap().width());
    }
    if(myPlane.y() > GameDefine::ScreenHeight - myPlane.pixmap().height()){
        myPlane.setY(GameDefine::ScreenHeight - myPlane.pixmap().height());
    }

}
